#include "imimp4_ffmpeg_api.h"
#include "imimp4_ffmpeg_api_impl.h"

#ifdef WIN32
#define LOGE
#else
#include "log.h"
#endif

using namespace imimp4_namespace;

handleMap<imimp4ffmpeg_impl> _HandleMap(1000);
std::list<imimp4ffmpeg_impl*> _HandleList;

IMIMP4_FFMPEG_LIB int IMIMp4FFmpeg_Init()
{
    imimp4_init_ffmpeg();
    return 0;
}

IMIMP4_FFMPEG_LIB int IMIMp4FFmpeg_Create_File(const char* path,
											   unsigned int container,
											   unsigned int video,
											   unsigned int audio,
											   unsigned int vfps,
											   unsigned int vwidth,
											   unsigned int vheight,
											   unsigned int achannel,
											   unsigned int asamplerate,
											   IMIMp4FFmpegHandle* pIMIhandle)
{
	imimp4ffmpeg_impl* impl = new imimp4ffmpeg_impl;
	int r = impl->create(path, (container_format_id)container, (video_codec_id)video, (audio_codec_id)audio, vfps, vwidth, vheight, achannel, asamplerate);
	if (r == 0)
	{
		*pIMIhandle = _HandleMap.getMap(impl);
		_HandleList.push_back(impl);
	}
	else
	{
		delete impl;
		*pIMIhandle = 0;
	}
	LOGE("IMIMp4FFmpeg_Create_File IMIMp4FFmpegHandle = %d\n", *pIMIhandle);
	return r;
}

IMIMP4_FFMPEG_LIB int IMIMp4FFmpeg_WriteVideoFrame(IMIMp4FFmpegHandle IMIhandle,
													 unsigned char* data,
													 unsigned int data_len,
													 unsigned int vtimestamp,
													 bool iskeyframe)
{
	imimp4ffmpeg_impl* impl = (imimp4ffmpeg_impl*)_HandleMap.getSomthing(IMIhandle);
	if (impl == 0) return imi_retcode_para;
	return impl->write_video(data, data_len, vtimestamp, iskeyframe);
}

IMIMP4_FFMPEG_LIB int IMIMp4FFmpeg_WriteAudioFrame(IMIMp4FFmpegHandle IMIhandle,
													 unsigned char* data,
													 unsigned int data_len,
													 unsigned int atimestamp)
{
  	LOGE("IMIMp4FFmpeg_WriteAudioFrame %d %d %d",data,data_len,atimestamp);

	imimp4ffmpeg_impl* impl = (imimp4ffmpeg_impl*)_HandleMap.getSomthing(IMIhandle);
	  	LOGE("IMIMp4FFmpeg_WriteAudioFrame impl   %d",impl);

	if (impl == 0) return imi_retcode_para;
	return impl->write_audio(data, data_len, atimestamp);
}

IMIMP4_FFMPEG_LIB int IMIMp4FFmpeg_CloseFileForCreate(IMIMp4FFmpegHandle IMIhandle)
{
	imimp4ffmpeg_impl* impl = (imimp4ffmpeg_impl*)_HandleMap.getSomthing(IMIhandle);
	if (impl == 0) return imi_retcode_para;
	return impl->close_create();
}

IMIMP4_FFMPEG_LIB int IMIMp4FFmpeg_Open_File(const char* path,
											 unsigned int* container,
											 unsigned int* video,
											 unsigned int* audio,
											 unsigned int* vfps,
											 unsigned int* vwidth,
											 unsigned int* vheight,
											 unsigned int* achannel,
											 unsigned int* asamplerate,
											 unsigned int* abitrate,
											 IMIMp4FFmpegHandle* pIMIhandle)
{
	imimp4ffmpeg_impl* impl = new imimp4ffmpeg_impl;
	int r = impl->open(path, (container_format_id*)container, (video_codec_id*)video, (audio_codec_id*)audio, vfps, vwidth, vheight, achannel, asamplerate, abitrate);
	if (r == 0)
	{
		*pIMIhandle = _HandleMap.getMap(impl);
		_HandleList.push_back(impl);
	}
	else
	{
		delete impl;
		*pIMIhandle = 0;
	}
	LOGE("IMIMp4FFmpeg_Open_File IMIMp4FFmpegHandle = %d\n", *pIMIhandle);
	return r;
}

IMIMP4_FFMPEG_LIB int IMIMp4FFmpeg_GetVideoFrame(IMIMp4FFmpegHandle IMIhandle,
												   unsigned char* data,
												   unsigned int* data_len,
												   unsigned int* timestamp,
												   bool* iskeyframe,
												   bool* isaudioframe)
{
	imimp4ffmpeg_impl* impl = (imimp4ffmpeg_impl*)_HandleMap.getSomthing(IMIhandle);
	if (impl == 0) return imi_retcode_para;
	return impl->get_frame(data, data_len, timestamp, iskeyframe, isaudioframe);
}

IMIMP4_FFMPEG_LIB int IMIMp4FFmpeg_CloseFileForOpen(IMIMp4FFmpegHandle IMIhandle)
{
	imimp4ffmpeg_impl* impl = (imimp4ffmpeg_impl*)_HandleMap.getSomthing(IMIhandle);
	if (impl == 0) return imi_retcode_para;
	return impl->close_open();
}